package com.contract.management.domain;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import com.contract.management.bean.page.PageBean;
import com.contract.management.bean.page.PageResult;

@Repository
public class CommJpaRepository {

	@PersistenceContext
	private EntityManager em;
	
	public EntityManager getEm() {
		return em;
	}
	
	public <T> List<T> query(String jpql, Object ...params) {
		Query query = em.createQuery(jpql);
		for(int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		return query.getResultList();
	}
	
	public <T> List<T> query(int maxResult, String jpql, Object ...params) {
		Query query = em.createQuery(jpql);
		for(int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		return query.setFirstResult(0).setMaxResults(maxResult).getResultList();
	}
	
	public <T> List<T> query(int startPosition, int maxResult, String jpql, Object ...params) {
		Query query = em.createQuery(jpql);
		for(int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		return query.setFirstResult(startPosition).setMaxResults(maxResult).getResultList();
	}

	public <T> List<T> query(String jpql, Map<String, Object> params) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		return query.getResultList();
	}
	
	public <T> List<T> query(String jpql, Map<String, Object> params, int startPosition, int maxResult) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		return query.setFirstResult(startPosition).setMaxResults(maxResult).getResultList();
	}
	
	public <T> List<T> query(String jpql, List<Object> params) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}
		}
		return query.getResultList();
	}
	
	public <T> List<T> query(String jpql, List<Object> params, int startPosition, int maxResult) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}	
		}
		return query.setFirstResult(startPosition).setMaxResults(maxResult).getResultList();
	}
	
	public PageResult query(PageBean pb, int startPosition, int maxResult) {
		PageResult ret = new PageResult();
		if(maxResult > 0) {
			List<Object[]> data = query(pb.getQl(), pb.getParams(), startPosition, maxResult);
			long sum = queryOne(pb.getSumQl(), pb.getParams());
			ret.setData(data);
			ret.setTotalCount(sum);
		} else {
			List<Object[]> data = query(pb.getQl(), pb.getParams());
			ret.setData(data);
			ret.setTotalCount(data.size());
		}
		return ret;
	}
	
	/**
	 * 查不到结果返回null, 查多个返回第一个.
	 * select count(*) from Object   =>  返回 Long
	 * @param jpql 		例如："select name from User where id > ?0 and name like ?1"
	 * @param params	例如：1, "admin%"
	 * @return
	 */
	public <T> T queryOne(String jpql, Object ...params) {
		Query query = em.createQuery(jpql);
		for(int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		List<T> list = query.setFirstResult(0).setMaxResults(1).getResultList();
		if(list == null || list.size() == 0) return null;
		return list.get(0);
	}
	
	public <T> T queryOne(String jpql, Map<String, Object> params) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
		}
		List<T> list = query.setFirstResult(0).setMaxResults(1).getResultList();
		if(list == null || list.size() == 0) return null;
		return list.get(0);
	}
	
	public <T> T queryOne(String jpql, List<Object> params) {
		Query query = em.createQuery(jpql);
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}
		}
		List<T> list = query.setFirstResult(0).setMaxResults(1).getResultList();
		if(list == null || list.size() == 0) return null;
		return list.get(0);
	}
	
	//返回实体类或 null
	public <T, ID extends Serializable> T find(Class<T> cls, ID id) {
		return em.find(cls, id);
	}
	
	public <T> void persist(T t) {
		em.persist(t);
	}
	
	public <T> T merge(T t) {
		return em.merge(t);
	}
	
	public <T> void remove(T t) {
		em.remove(t);
	}
	
	/**
	 * 采用jpql语句修改、删除数据。
	 * @param jpql		采用JPA占位符方式，例如： "update Book b set b.name = ?0 where b.id = ?1";
	 * @param params	必须按0,1,2... 顺序排列
	 * @return
	 */
	public int queryUpdate(String jpql, Object ...params) {
		Query query = em.createQuery(jpql);
		for(int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
		return query.executeUpdate();
	}
}
